package com.yanqu.road.dao.impl.activity.hotpotjump;

import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDao;
import com.yanqu.road.entity.autodata.AutoActivityConfigClazzInfo;
import com.yanqu.road.entity.autodata.AutoActivityConfigObject;

import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CommonLocalConfigDaoImpl<T extends AutoActivityConfigObject> extends TempDao {

    public List<T> getConfigList(Class<T> clazz) {
        List<T> dataList = new ArrayList<>();
        ResultSet rs = null;
        CallableStatement call = null;
        try {
            AutoActivityConfigClazzInfo clazzInfo = AutoActivityConfigObject.getAutoActivityConfigClazzInfo(clazz);
            if (clazzInfo == null) {
                return null;
            }
            String tableName = clazzInfo.getTableName();
            String sql = "select * from " + tableName;

            getDb().setConnName(DbNameStrategy.getConfigDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                T instance = parseInstance(clazz, rs);
                dataList.add(instance);
            }
        } catch (Throwable e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataList;
    }

    private T parseInstance(Class<T> clazz, ResultSet rs) throws Throwable {
        AutoActivityConfigClazzInfo clazzInfo = AutoActivityConfigObject.getAutoActivityConfigClazzInfo(clazz);
        if (clazzInfo == null) {
            return null;
        }
        Constructor<?> constructor = clazzInfo.getConstructor();
        T instance = (T) constructor.newInstance();
        // 设置字段值
        Map<Field, MethodHandle> handleMap = clazzInfo.getFieldSetterMethodHandleMap();
        for (Map.Entry<Field, MethodHandle> entry : handleMap.entrySet()) {
            Field field = entry.getKey();
            MethodHandle handle = entry.getValue();
            Object value = rs.getObject(field.getName());
            if (value != null) {
                handle.invoke(instance, value);
            }
        }
        return instance;
    }


}
